package org.activityinfo.server.mail;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import freemarker.template.Configuration;
import org.activityinfo.service.DeploymentConfiguration;
import org.activityinfo.server.util.logging.LogException;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import java.io.*;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
/**
* Sends mail messages by SMTP using the javax.mail API.
*/
public class SmtpMailSender extends MailSender {
private static final Logger LOGGER = Logger.getLogger(SmtpMailSender.class.getName());
private final DeploymentConfiguration configuration;
@Inject
public SmtpMailSender(DeploymentConfiguration configuration, Configuration templateCfg) {
super(templateCfg);
this.configuration = configuration;
}
@Override @LogException
public void send(Message message) {
try {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setSubject(message.getSubject(), Charsets.UTF_8.name());
mimeMessage.addRecipients(RecipientType.TO, toArray(message.getTo()));
mimeMessage.addRecipients(RecipientType.BCC, toArray(message.getBcc()));
mimeMessage.setFrom(new InternetAddress(configuration.getProperty("smtp.from",
"activityinfo@configure-me.com"), configuration.getProperty("smtp.from.name", "ActivityInfo")));
if (message.getReplyTo() != null) {
mimeMessage.setReplyTo(new Address[]{message.getReplyTo()});
}
String body;
if (message.hasHtmlBody()) {
body = message.getHtmlBody();
mimeMessage.setDataHandler(new DataHandler(new HTMLDataSource(body)));
} else {
body = message.getTextBody();
mimeMessage.setText(body, Charsets.UTF_8.name());
}
LOGGER.finest("message to " + message.getTo() + ":\n" + body);
if (!message.getAttachments().isEmpty()) {
Multipart multipart = new MimeMultipart();
for (MessageAttachment attachment : message.getAttachments()) {
MimeBodyPart part = new MimeBodyPart();
part.setFileName(attachment.getFilename());
DataSource src = new ByteArrayDataSource(attachment.getContent(), attachment.getContentType());
part.setDataHandler(new DataHandler(src));
multipart.addBodyPart(part);
}
mimeMessage.setContent(multipart);
}
mimeMessage.saveChanges();
Transport.send(mimeMessage);
} catch (MessagingException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private Address[] toArray(List<InternetAddress> to) {
return to.toArray(new Address[to.size()]);
}
static class HTMLDataSource implements DataSource {
private String html;
public HTMLDataSource(String htmlString) {
// transform non-ascii characters into entities to avoid
// encoding issues
}
@Override
public InputStream getInputStream() throws IOException {
if (html == null) {
throw new IOException("Null HTML");
}
return new ByteArrayInputStream(html.getBytes());
}
@Override
public OutputStream getOutputStream() throws IOException {
throw new IOException("This DataHandler cannot write HTML");
}
@Override
public String getContentType() {
return "text/html; charset=UTF-8";
}
@Override
public String getName() {
return "text/html dataSource";
}
}
}